﻿using System;
using System.Collections.Generic;
using System.ComponentModel;

using G.Runtime;
using GameLibrary.Model;
using GameLibrary.Model.Enums;

namespace Conquest
{
    public class Homeland : Component, HasGameSpace
    {
        public enum StateEnum
        {
            Full,
            PartlyFilled,
            Empty
        }
        
        public delegate void HomelandHandler(Homeland homland);
        public event HomelandHandler StateChanged;
        
        private GameSpace _Space;
        private string _PlayerName = "Player1";
        private StateEnum _State;
        private int _FullCount;
        
        public Homeland()
        {
            _Space = CreateSpace();
            _State = StateEnum.Empty;
        }
        
        public StateEnum State
        {
            get { return _State; }
            set
            {
                if (_State == value)
                {
                    return;
                }
                _State = value;
                if (StateChanged != null)
                {
                    StateChanged(this);
                }
            }
        }

        public string PlayerName
        {
            get { return _PlayerName; }
            set
            {
                _PlayerName = value;
                
                foreach (GameElementDef def in _Space.GameDef.GameElementDefs)
                {
                    def.Player = value;
                }
                
                foreach (GameElement element in _Space.Elements)
                {
                    element.Player = value;
                }
            }
        }
        
        private GameSpace CreateSpace()
        {
            GameSpaceDef def = new GameSpaceDef();
            def.Height = 3;
            def.Width = 4;
            
            for (int x = 0; x < def.Width; x++)
            {
                GameElementDef element = new GameElementDef(
                    def, new GameLocation(x, 0));
                element.MoveStratagy = MoveStratagyEnum.NO_MOVE;
                element.Icon = "";
                element.Player = _PlayerName;
                element.Text = "" + (x + 1);
                def.GameElementDefs.Add(element);
            }
            
            GameSpace space = new GameSpace(def);
            space.Elements.Click += OnClick;
            space.Elements.ElementRemovedEvent += OnElementRemoved;
            return space;
        }

        private void CheckState()
        {
            int count = this.CountMen;
            if (count == 0) 
            {
                State = StateEnum.Empty;
            }
            else
            {
                if (count == _FullCount)
                {
                    State = StateEnum.Full;
                }
                else
                {
                    State = StateEnum.PartlyFilled;
                }
            }
        }
        
        public int CountMen
        {
            get
            {
                int result = 0;
                foreach (GameElement element in _Space.Elements)
                {
                    if (element.Location.Y > 0)
                    {
                        result++;
                    }
                }
                return result;
            }
        }
        
        private void AddElements(int number)
        {
            int count = 0;
            bool exit = false;
            _FullCount = number;
            
            for (int x = 0; x < _Space.GameDef.Width; x++)
            {
                for (int y = 1; y < _Space.GameDef.Height; y++)
                {
                    GameElementDef def = new GameElementDef(
                        _Space.GameDef, new GameLocation(x, y));
                    def.MoveStratagy = MoveStratagyEnum.NO_MOVE;
                    def.Player = _PlayerName;
                    
                    if (_Space.GameDef.GameElementDefs.Contains(def))
                    {
                        _Space.GameDef.GameElementDefs.Add(def);
                    }
                    
                    GameElement element = new GameElement(def, _Space);
                    _Space.Elements.Add(element);
                    
                    count++;
                    if (count >= number)
                    {
                        exit = true;
                        break;
                    }
                }
                
                if (exit)
                {
                    break;
                }
            }
            
            this.State = StateEnum.Full;
        }
        
        [Browsable(false)]
        public GameSpace Game
        {
            get { return _Space; }
        }
        
        private void OnClick(ElementEventArgs args)
        {
            if (args.element != null && args.element.Location.Y > 0 )
            {
                SelectedElement.GameElement = args.element;
            }
            else if (CountMen == 0)
            {
                int numnber = 0;
                int.TryParse(args.element.Text, out numnber);
                _Space.Elements.Remove(args.element);
                AddElements(numnber);
                CheckState();
            }
        }
        
        private void OnElementRemoved(GameElement subject)
        {
            CheckState();
        }

    }
}
